#include "stimpy.h"
#include "fileio.h"

void ShowAlertAlreadyRunning()
{
	MessageBoxW(NULL, L"This program is already running!", L"Warning!", MB_ICONWARNING);
}

void ShowAlertCurrentExe()
{
	char szFileName[MAX_PATH];
	HINSTANCE hInstance = GetModuleHandle(NULL);
	GetModuleFileName(hInstance, (LPWSTR)szFileName, MAX_PATH);
	MessageBoxW(NULL, (LPWSTR)szFileName, L"About Stimpy", MB_OK | MB_ICONINFORMATION);
}

void OpenFile(HWND hWnd)
{
	LPWSTR pwszBuf = (LPWSTR)GlobalAlloc(GPTR, (MAX_PATH) * sizeof(WCHAR));

	ZeroMemory(&ofn, sizeof(ofn));
	ofn.hwndOwner = hWnd;
	ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
	ofn.lpstrFile = pwszBuf;
	ofn.lStructSize = sizeof(ofn);
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	ofn.lpstrDefExt = L"txt";
	if(GetOpenFileName(&ofn))
		LoadTextFileToEdit(GetDlgItem(hWnd, IDC_MAIN_EDIT), ofn.lpstrFile);
}

void SaveFile(HWND hWnd)
{
	SaveTextFileFromEdit(GetDlgItem(hWnd, IDC_MAIN_EDIT), ofn.lpstrFile);
}

BOOL CALLBACK StringListDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message)
	{
	case WM_LBUTTONDOWN:
		return TRUE;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDC_POMLIST:
			switch(HIWORD(wParam))
			{
			case LBN_SELCHANGE:
				HWND hList = GetDlgItem(hWnd, IDC_POMLIST);
				int index = SendMessage(hList, LB_GETCURSEL, 0, 0);
				if(index >= 0) {
					int data = SendMessage(hList, LB_GETITEMDATA, (WPARAM)index, 0);
					SetDlgItemInt(hWnd, IDC_TIMERLBL, data, FALSE);
				}
				break;
			}
			break;
		case IDSAVE:
			{
				// NB: GetWindowTextLength does *not* include the null terminator!
				int nLength = GetWindowTextLength(GetDlgItem(hWnd, IDC_TIMERLBL));
				if(nLength > 0)
				{
					BOOL bSuccess = false;
					int nTimerLen = GetDlgItemInt(hWnd, IDC_TIMERLEN, &bSuccess, FALSE);
					if(bSuccess) {
						for(int i=0; i < nTimerLen; i++)
							SendDlgItemMessage(hWnd, IDC_POMLIST, LB_ADDSTRING, 42, (LPARAM)L"Pomodoro Complete");
					} else {
						LPWSTR pwszBuf = (LPWSTR)GlobalAlloc(GPTR, (nLength + 1) * sizeof(WCHAR));
						int nCopied = GetDlgItemText(hWnd, IDC_TIMERLEN, pwszBuf, nLength + 1);
						OutputDebugString(pwszBuf);
						GlobalFree(pwszBuf);
					}
				}
				else
				{
					SetDlgItemText(hWnd, IDC_TIMERLEN, L"Enter text here..");
				}
			}
			break;
		case IDCANCEL:
			EndDialog(hWnd, IDCANCEL);
			break;
		}
		break;
	default:
		return FALSE;
	}
	return true;
}

LRESULT CALLBACK WndProc(
	HWND hWnd,
	UINT msg,
	WPARAM wParam,
	LPARAM lParam)
{
	switch(msg)
	{
	case WM_LBUTTONDOWN:
		break;
	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;
	case WM_CREATE:
		{
			// Edit Box
			DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL;
			HWND hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", dwStyle, 0, 0, 0, 0, hWnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
			if(hEdit == NULL)
				MessageBox(hWnd, L"Could not create edit box.", L"Error", MB_OK | MB_ICONERROR);

			HGDIOBJ hfDefault = GetStockObject(DEFAULT_GUI_FONT);
			SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));

			// Toolbar
			TBBUTTON tbb[3];
			TBADDBITMAP tbab;
			tbab.hInst = HINST_COMMCTRL;
			tbab.nID = IDB_STD_SMALL_COLOR;
			
			ZeroMemory(tbb, sizeof(tbb));
			tbb[0].iBitmap = STD_FILENEW;
			tbb[0].fsState = TBSTATE_ENABLED;
			tbb[0].fsStyle = TBSTYLE_BUTTON;
			tbb[0].idCommand = IDR_OPEN;
			
			tbb[1].iBitmap = STD_FILEOPEN;
			tbb[1].fsState = TBSTATE_ENABLED;
			tbb[1].fsStyle = TBSTYLE_BUTTON;
			tbb[1].idCommand = IDR_SAVE;
			
			tbb[2].iBitmap = STD_FILESAVE;
			tbb[2].fsState = TBSTATE_ENABLED;
			tbb[2].fsStyle = TBSTYLE_BUTTON;
			tbb[2].idCommand = IDR_SAVE;

			HWND hToolbar = CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE, IDC_MAIN_TOOL, 3, 0, 0, (LPCTBBUTTON)&tbb, 3, 16, 16, 0, 0, sizeof(TBBUTTON));

			SendMessage(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbab);

			ShowWindow(hToolbar, SW_SHOW);
		}
		break;
	case WM_SIZE:
		{
			RECT rcTool;
			HWND hTool = GetDlgItem(hWnd, IDC_MAIN_TOOL);
			SendMessage(hTool, TB_AUTOSIZE, 0, 0);
			GetWindowRect(hTool, &rcTool);
			int iToolHeight = rcTool.bottom - rcTool.top;

			HWND hEdit;
			RECT rcClient;
			GetClientRect(hWnd, &rcClient);
			int iEditHeight = rcClient.bottom - iToolHeight;
			hEdit = GetDlgItem(hWnd, IDC_MAIN_EDIT);
			SetWindowPos(hEdit, NULL, 0, iToolHeight, rcClient.right, iEditHeight, SWP_NOZORDER);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDR_OPEN:
			OpenFile(hWnd);
			break;
		case IDR_SAVE:
			SaveFile(hWnd);
			break;
		case IDR_SETTINGS:
			DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_APP_SETTINGS), hWnd, StringListDlgProc);
			break;
		case IDR_EXIT:
			PostQuitMessage(0);
			break;
		case IDR_ABOUT:
			ShowAlertCurrentExe();
			break;
		default:
			break;
		}
	default:
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(
	HINSTANCE hInstance, 
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hWnd;
	MSG msg;
	SECURITY_ATTRIBUTES sa;
	DWORD err;

	InitCommonControls();

	// Only one instance of this application at a time, please!
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = NULL;
	sa.lpSecurityDescriptor = NULL;

	CreateMutex(&sa, TRUE, L"MY_COOL_MUTEX.TXT");
	err = GetLastError();
	if(err == ERROR_ALREADY_EXISTS)
	{
		ShowAlertAlreadyRunning();
		return -1;
	}

	OutputDebugString(L"Stimpy Application Started!");

	// register the window class
	wc.cbSize			= sizeof(WNDCLASSEX);
	wc.style			= 0;
	wc.lpfnWndProc		= WndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInstance;
	wc.hIcon			= LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APP_ICON));
	wc.hIconSm			= NULL;
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName		= MAKEINTRESOURCE(IDR_APP_MENU);
	wc.lpszClassName	= (LPCWSTR)g_szClassName;

	if(!RegisterClassEx(&wc)) {
		MessageBox(NULL, L"Windows registration failed!", L"Error", MB_OK|MB_ICONEXCLAMATION);
		return 0;
	}

	hWnd = CreateWindowEx(
		WS_EX_APPWINDOW, // WS_EX_CLIENTEDGE,
		(LPCWSTR)g_szClassName,
		L"Stimpy",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		640,
		480,
		NULL,
		NULL,
		hInstance,
		NULL);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATORS));

	while(GetMessage(&msg, NULL, 0, 0) > 0)
	{
		if (!TranslateAccelerator(hWnd, hAccel, &msg))
        {
			// Without TranslateMessage the Alt keys to access menus won't work
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
	}

	return msg.wParam;
}
